/*
 * author      : 吴中勤 
 * date        : 2019/3/21
 * description : TODO
 */

package org.wzq.learn.infrastructure.lib.trace.threadpool;

import brave.Tracing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.sleuth.SpanNamer;
import org.springframework.cloud.sleuth.instrument.async.TraceRunnable;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.wzq.learn.infrastructure.lib.trace.CustomThreadContext;

import static java.lang.Thread.UncaughtExceptionHandler;

class RunnableWrapper extends TraceRunnable {

    private static final Logger logger = LoggerFactory.getLogger(RunnableWrapper.class);
    private final CustomThreadContext.ContextAttributes contextAttributes;
    private final UncaughtExceptionHandler exceptionHandler;
    private final RequestAttributes context;

    RunnableWrapper(Runnable task,
                    CustomThreadContext.ContextAttributes obj,
                    RequestAttributes context,
                    UncaughtExceptionHandler handler,
                    Tracing tracing,
                    SpanNamer spanNamer) {
        super(tracing, spanNamer, task);
        RequestContextHolder.setRequestAttributes(RequestContextHolder.currentRequestAttributes(), true);
        this.contextAttributes = obj;
        this.context = context;
        this.exceptionHandler = handler;
    }

    @Override
    public void run() {
        if (logger.isInfoEnabled())
            logger.info("RunnableWrapper::run start, threadId=" + Thread.currentThread().getId());

        if (exceptionHandler != null) {
            Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler);
        }
        if (context != null) {
            RequestContextHolder.setRequestAttributes(context);
        }

        // 将变量设置到线程的变量中去, 此时已经在 线程 中
        CustomThreadContext.bindContextAttributes(contextAttributes);

        try {
            super.run();
        } finally {
            RequestContextHolder.resetRequestAttributes();
        }
    }
}